namespace Wiki.Web.Mvc
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Net;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Xml;

    public sealed class SeeOtherActionResult : ActionResult
    {
        private const string HtmlTemplate = "<html>" +
            "<head><title>The information you requested has been found</title></head>" +
            "<body>" +
            "<h1>The information you requested has been found</h1>" +
            "<p><a id=\"location\" href=\"\"></a></p>" +
            "</body>" +
            "</html>";

        private Uri _location;

        public SeeOtherActionResult(Uri location)
        {
            this.Location = location;
        }

        public Uri Location
        {
            get
            {
                return _location;
            }

            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("value");
                }

                if (!value.IsAbsoluteUri)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                _location = value;
            }
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (null == context)
            {
                throw new ArgumentNullException("context");
            }

            HttpResponseBase response = context.HttpContext.Response;

            response.StatusCode = (int)HttpStatusCode.SeeOther;
            response.AppendHeader("Location", this.Location.AbsoluteUri);
            response.ContentType = "text/html";
            response.Cache.SetCacheability(HttpCacheability.Public);
            response.Cache.SetExpires(DateTime.UtcNow.AddDays(1));

            XmlDocument content = new XmlDocument();
            content.LoadXml(HtmlTemplate);
            content.SelectSingleNode("/html/body/p/a[@id='location']/@href").Value = this.Location.AbsoluteUri;
            content.SelectSingleNode("/html/body/p/a[@id='location']").InnerText = HttpUtility.HtmlEncode(this.Location.AbsoluteUri);

            response.Write(content.OuterXml);
        }
    }
}